Typisierung von Ausdrücken

Neuron Power Engineer →typisiert →Ausdrücke und →Zuweisungen laut diesen Regeln:

  • Der Datentyp der →Variable, die das Ergebnis einer →überladenen Funktion erhält, beeinflusst den Datentyp des Ergebnisses für eine Funktion oder Operation. Diese Regel entspricht nicht den Vorgaben der →IEC-Norm.

    Beispiele
    VAR
      int1, int2, int3 : INT := 32767;
      dint1 : DINT := 32767;
      ResultInt1 : INT;
      ResultDint1, ResultDint2 : DINT;  
    END_VAR
     
    ResultInt1  := int1 + int2;    (* The addition is performed as an INT-operation. *)
    ResultDint1 := int1 + int2;    (* In contrast to the IEC-standard: 'int1' and 'int2' are converted to DINT. The addition is performed as an DINT-operation and assigned to 'ResultDint1'. *)
    ResultDint2 := dint1 + int3;   (* 'int3' is converted to DINT. The addition is performed as a DINT addition. *)
  • Falls in den Ausdrücken gar kein konkreter Datentyp angeführt ist, wird die Typisierung ebenfalls vom Datentyp der Variable beeinflusst, die das Ergebnis einer überladenen Funktion erhält. Diese Zusatz-Regel ist eine implementierungsabhängige Realisierung, da die IEC-Norm keine Vorgaben dazu enthält.

    Beispiele
    VAR
      ResultDintA, ResultDintB, ResultDintC : DINT;
      sint1 : SINT := 127;
    END_VAR     
     
    ResultDintA := 127 + 127;       (* The addition is performed as an DINT-operation because there is no other concrete data type. *)
    ResultDintB := 127 + SINT#127;  (* 'SINT#127' is converted to DINT. The addition is performed as an DINT-operation and assigned to 'ResultDintB'. *)
    ResultDintC := 127 + sint1;     (* 'sint1' is converted to DINT. The addition is performed as an DINT-operation and assigned to 'ResultDintC'.*)
  • Bei einem →Aufruf, der Eingänge, Ausgänge und/oder einen Ergebniswert mit dem gleichen →allgemeinen Datentyp verwendet, typisiert Neuron Power Engineer alle diese Eingänge, Ausgänge und den Ergebniswert des Aufrufs, sogar falls nur eines dieser Elemente mit einem konkreten Datentyp verbunden ist.

    Beispiele
    VAR
      Var1, OUT1 : INT;
      iForceMrk1 : FORCEMRK;
    END_VAR
     
    Var1 := ADD(IN1 := 1, IN2 := 3);
    (* The inputs and the return value of 'ADD' are using the same generic data type. As the INT variable 'Var1' is assigned to the call of 'ADD' (in particular to the return value of 'ADD'), the call is typed with 'INT'. Subsequently, the inputs of 'ADD' are typed with 'INT' as well. *)
     
    iForceMrk1(IN := 3, OUT => OUT1);
    (* The input and the output of 'FORCEMRK' are using the same generic data type. As output 'OUT' of 'iForceMrk1' is assigned to the INT variable 'OUT1', the call is typed with 'INT'. Subsequently, the input of 'iForceMrk1' is typed with 'INT' as well. *)

    Falls ein →anwenderdefinierter Datentyp zur Typisierung verwendet wird, verwendet Neuron Power Engineer den →Basistyp. Diese Regel ist von Bedeutung, falls ein →Initialisierungswert im anwenderdefinierten Datentyp definiert ist – in diesem Fall wird nicht der Initialisierungswert des Datentyps verwendet, sondern der Initialisierungswert des Basistyps.
    Vergleichen Sie: Bei einem →ARRAY-Datentyp (inkl. einer ARRAY-Deklaration einer Variable) oder einem →strukturiertem Datentyp ist der anwenderdefinierte Datentyp jedoch der Basistyp.

    Beispiele
    TYPE
      MyInt : INT := 6;
      MyStruct : Struct
        Elem1 : MyInt;
      END_STRUCT;
      MyArray : Array [1..1] OF MyInt := [99];
    END_TYPE
     
    FUNCTION_BLOCK myFB
      VAR
        outDerived : MyInt;
        outArray1 : MyArray;
        outArray2 : Array [1..1] OF MyInt;
        outStruct : MyStruct;    
        iForceMrk1, iForceMrk2, iForceMrk3, iForceMrk4 : FORCEMRK;
      END_VAR
     
      iForceMrk1(OUT => outDerived);
      (* 'OUT' gets value '0' because initial value '0' of 'INT' is used. Here the base type is 'INT'. *)
      (* The initial value '6' of 'MyInt' is NOT used. *)
      
      iForceMrk2(OUT => outArray1);
      iForceMrk3(OUT => outArray2);
      iForceMrk4(OUT => outStruct);
      (* Each element of output 'OUT' gets value '6' because initial value '6' of 'MyINT' is used. *)
      (* Here the base type of each element is 'MyInt* while the base type of 'OUT' is 'ARRAY [...] OF' or 'STRUCT'. *)
      
    END_FUNCTION_BLOCK
  • Falls 2 oder mehrere Aufrufe miteinander verbunden sind, bei denen die verbundenen Eingänge, Ausgänge und/oder der verbundene Ergebniswert von einem allgemeinen Datentyp sind (die anderen jedoch von einem konkreten Datentyp), typisiert Neuron Power Engineer alle diese Eingänge, Ausgänge und den Ergebniswert des Aufrufs auf den kleinsten gemeinsamen Datentyp.
    Beispiel: Beim PACK-Baustein ist der Ergebniswert vom allgemeinen Datentyp ANY_ELEMENTARY und die Eingänge vom konkreten Datentyp BYTE, beim TO_DINT-Baustein ist der Eingang ebenfalls vom allgemeinen Datentyp ANY_ELEMENTARY und  der Ergebniswert vom konkreten Datentyp DINT.
    Für Versionen vor 3.25.0 und beim folgenden Code wurde der Ergebniswert von PACK und der Eingang von TO_DINT mit BOOL typisiert (BOOL ist der kleinster gemeinsame Datentyp von ANY_ALEMENTARY).
    Für Version 3.25.0 und nachfolgende Versionen wird der Code als fehlerhaft markiert, da der Ergebniswert von PACK in diesen Versionen nicht mit einem Baustein-Eingang eines allgemeinen Datentyps verbunden werden darf.

    Beispiel
    VAR
      Var1 : DINT;
      ByteVar1 : BYTE:= 16#AB;
    END_VAR
     
    Var1 := TO_DINT(PACK(ByteVar1, ByteVar1)); (* This line is highlighted as faulty in V3.25.0 and later. *)

    Brechen Sie die Verschachtelung auf, um die Typisierung auf den kleinsten gemeinsamen Datentyp oder den für PACK gemeldeten Fehler zu umgehen.
    Abhilfe 1: Erstellen Sie eine Hilfsvariable. Weisen Sie einen Aufruf dieser Hilfsvariable zu. Beim anderen Aufruf wiesen Sie diese Hilfsvariable als Parameter zu.

    Beispiel für Abhilfe 1

    VAR
      Var1 : DINT;
      ByteVar1 : BYTE := 16#AB;
      HelperVar : DINT;                        (* the auxiliary variable *) 
    END_VAR
     
    HelperVar := PACK(ByteVar1, ByteVar1);
    Var1 := TO_DINT(HelperVar);                (* 'Var1' evaluates to value '43947'. This a value as expected from 'PACK' *)

    Abhilfe 2: Erstellen Sie eine benutzerdefinierte POE (z.B. eine Funktion). Weisen Sie einen Aufruf der Bausteine (im folgenden Beispiel: PACK) dem Ergebniswert der Funktion zu. Rufen Sie die Funktion als Parameter des anderen Bausteins (dann: DINT) auf.

    Beispiel für Abhilfe 2
    FUNCTION myFun1 : DWORD
      VAR
        ByteVar1 : BYTE:= 16#AB;
      END_VAR
     
      myFun1 := PACK(ByteVar1, ByteVar1);     (* 'PACK' is assigned to the return value of function 'myFun1'. *)
    END_FUNCTION
     
    FUNCTION_BLOCK myFB2
      VAR
        Var1 : DINT;
      END_VAR
      
      Var1 := TO_DINT(IN:=myFun1());           (* 'Var1' evaluates to value '43947'. This a value as expected from 'PACK'. *)
    END_FUNCTION_BLOCK